package models

import (
	"errors"
	"fmt"
	"time"
	"toy-car/pkg/util"

	"github.com/unknwon/com"
	"gorm.io/gorm"
)

type SysUser struct {
	ID        uint           `json:"id" gorm:"primarykey"` // 主键ID
	CreatedAt time.Time      // 创建时间
	UpdatedAt time.Time      // 更新时间
	DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` // 删除时间
	// UUID        uuid.UUID    `json:"uuid" gorm:"comment:用户UUID"`                                                    // 用户UUID
	Username    string `json:"userName" gorm:"comment:用户登录名" form:"userName"`                              // 用户登录名
	Password    string `json:"-"  gorm:"comment:用户登录密码"`                                                   // 用户登录密码
	Name        string `json:"nickName" gorm:"default:系统用户;comment:用户昵称" form:"nickName"`                  // 用户昵称
	HeaderImg   string `json:"avatar" gorm:"default:http://qmplusimg.henrongyi.top/head.png;comment:用户头像"` // 用户头像
	AuthorityId uint   `json:"authorityId" gorm:"index;default:888;comment:用户角色ID"`                        // 用户角色ID
	// Authority    SysAuthority   `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"`
	AuthorityIds []uint         `json:"authorityIds" gorm:"-"`
	Authorities  []SysAuthority `json:"authorities" gorm:"many2many:sys_user_authority;"`
	Enable       int            `json:"enable" gorm:"default:1;comment:用户是否被冻结 1正常 2冻结"` //用户是否被冻结 1正常 2冻结
}

func CheckAndFetchAuth(username, password string) SysUser {
	var auth SysUser
	md5Pass := util.MD5V([]byte(password))
	fmt.Println("pass", md5Pass)
	db.Where(SysUser{Username: username, Password: md5Pass}).First(&auth)
	return auth
}

func RegistAuth(a SysUser) (err error, info SysUser) {
	var oldUser SysUser
	err = db.Where("username = ?", a.Username).First(&oldUser).Error
	if !errors.Is(err, gorm.ErrRecordNotFound) {
		return errors.New("用户名已经被占用"), info
	}

	a.Password = util.MD5V([]byte(a.Password))
	err = db.Create(&a).Error
	return err, a
}

func ChangePassword(a *SysUser, password string) (err error, info *SysUser) {
	var oldUser SysUser
	a.Password = util.MD5V([]byte(a.Password))
	err = db.Where("username = ? AND password = ?", a.Username, a.Password).First(&oldUser).Update("password", util.MD5V([]byte(password))).Error
	return err, a
}

func ResetPassword(a *SysUser) (err error, info *SysUser) {
	var oldUser SysUser
	a.Password = util.MD5V([]byte(a.Password))
	err = db.Where("id = ?", a.ID).First(&oldUser).Update("password", util.MD5V([]byte("123456"))).Error
	return err, a
}

func GetPagedUsers(page, pageSize int, where interface{}) (err error, list []SysUser, total int64) {
	var userList []SysUser
	offset := pageSize * (page - 1)
	err = db.Model(&userList).Count(&total).Error
	err = db.Where(where).Limit(pageSize).Offset(offset).Order("id DESC").Find(&userList).Error
	return err, userList, total
}

func DeleteUser(id int) (err error) {
	var user SysUser
	return db.Where("`id` = ?", id).Delete(&user).Error
}

func ChangeAuthority(uid int, aid string) (err error) {
	return db.Where("id = ?", uid).First(&SysUser{}).Update("role", com.StrTo(aid).String()).Error
}

func UpdateUser(user SysUser, id int) (err error, u SysUser) {
	err = db.Model(&SysUser{}).Where("id = ?", id).Updates(&user).Error
	return err, user
}

func GetUserByName(name string) (SysUser, error) {
	var user SysUser
	err := db.Where("username = ?", name).First(&user).Error
	return user, err
}

func SetUserAuthorities(id uint, authirutes []uint) error {
	return db.Transaction(func(tx *gorm.DB) error {
		TxErr := tx.Delete(&[]SysUserAuthority{}, "sys_user_id = ?", id).Error
		if TxErr != nil {
			return TxErr
		}
		var useAuthority []SysUserAuthority
		for _, v := range authirutes {
			useAuthority = append(useAuthority, SysUserAuthority{
				SysUserId: id, SysAuthorityAuthorityId: v,
			})
		}
		TxErr = tx.Create(&useAuthority).Error
		if TxErr != nil {
			return TxErr
		}
		TxErr = tx.Where("id = ?", id).First(&SysUser{}).Update("authority_id", authirutes[0]).Error
		if TxErr != nil {
			return TxErr
		}
		// 返回 nil 提交事务
		return nil
	})
}
